package com.wbpay.sdk.wrapper;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.wbpay.sdk.dlg.CancelPayDialog;
import com.wbpay.sdk.framework.PayResult;
import com.wbpay.sdk.framework.ResponseCallback;
import com.wbpay.sdk.http.Response;
import com.wbpay.sdk.request.IPayRequest;
import com.wbpay.sdk.request.PayRequestImpl;
import com.wbpay.sdk.utils.Log;
import com.wbpay.sdk.utils.Utils;

import org.json.JSONObject;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * 聚宝支付activity
 */
public class SwiftPayWrapper extends ActivityWrapper {

    private IPayRequest mPayRequest = null;
    private Handler mHandler = null;
    private ProgressDialog mProgressDialog;
    // 此处的appId和channel通过intent传递是由于此代码在单独的进程中
    private String appId;
    private String channel;

    // 关闭回调
    private static final String JS_PAY_CANCEL = ""
            + "function doCallback() {"
            + "     try {"
            + "         swiftpay.notifyWebPayResult(2, '支付取消');"
            + "     } catch(e) {"
            + "     }"
            + "}";

    private WebView mWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        String url = getPayUrl();
        Log.d(Log.TAG, "url : " + url);
        if (TextUtils.isEmpty(url)) {
            notifyPayResult(PayResult.PAY_FAILURE, getActivity().getString(Utils.getStringId(getActivity(), "jy_url_not_found")));
            return;
        }
        fetchParams();
        mHandler = new Handler(Looper.getMainLooper());
        mPayRequest = new PayRequestImpl(getActivity());
        mWebView = new WebView(getActivity());
        getActivity().setContentView(mWebView);
        mWebView.addJavascriptInterface(this, "swiftpay");
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new WebViewClient() {
            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                Log.d(Log.TAG, "url : " + url);
                if (url.startsWith("weixin:")) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    try {
                        getActivity().startActivity(intent);
                    } catch (Exception e) {
                        super.shouldOverrideUrlLoading(webView, url);
                    }
                    return true;
                } else if (url.startsWith("whalepay:")) {
                    querySwiftPayResult(url, parseQuery(url));
                    return true;
                }
                return super.shouldOverrideUrlLoading(webView, url);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                Log.d(Log.TAG, "url : " + url);
                // 注入关闭js代码
                mWebView.loadUrl("javascript:" + JS_PAY_CANCEL);
            }
        });
        // 加载支付 url
        mWebView.loadUrl(url);
    }

    private String getPayUrl() {
        try {
            return getActivity().getIntent().getStringExtra("pay_url");
        } catch(Exception e) {
        }
        return null;
    }

    private void fetchParams() {
        try {
            appId = getActivity().getIntent().getStringExtra("appid");
            channel = getActivity().getIntent().getStringExtra("channel");
        } catch(Exception e) {
        }
    }

    @JavascriptInterface
    public void notifyWebPayResult(int code, String desc) {
        notifyPayResult(code, desc);
    }

    private void notifyPayResult(int code, String desc) {
        Utils.sendPayResult(getActivity(), code, desc, getCallbackAction());
        dismissProgress();
        getActivity().finish();
    }

    /**
     * 显示进度条
     */
    private void showProgress(final String desc) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mProgressDialog = ProgressDialog.show(getActivity(), null, desc);
                mProgressDialog.setCancelable(false);
                mProgressDialog.setCanceledOnTouchOutside(false);
            }
        });
    }

    /**
     * 关闭进度条
     */
    private void dismissProgress() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mProgressDialog != null && mProgressDialog.isShowing()) {
                    mProgressDialog.dismiss();
                    mProgressDialog = null;
                }
            }
        });
    }

    /**
     * 解析URL
     * @param url
     * @return
     */
    private Map<String, String> parseQuery(String url) {
        Map<String, String> map = null;
        try {
            URI uri = new URI(url);
            String query = uri.getQuery();
            String args[] = query.split("&");
            map = new HashMap<String, String>();
            for (String arg : args) {
                if (arg != null) {
                    String tmp[] = arg.split("=");
                    if (tmp != null && tmp.length == 2) {
                        map.put(tmp[0], tmp[1]);
                    }
                }
            }
        } catch(Exception e) {
        }
        return map;
    }

    /**
     * 根据URL查询订单结果
     * @param url
     * @param params
     */
    private void querySwiftPayResult(final String url, final Map<String, String> params) {
        showProgress(getActivity().getString(Utils.getStringId(getActivity(), "jy_querying_pay_result")));
        // 显示空白页是为了防止在查询订单结果的过程中，此函数为被多次调用
        mWebView.loadUrl("about:blank");
        String orderId = null;
        if (params != null && params.containsKey("order_id")) {
            orderId = params.get("order_id");
        }
        Log.d(Log.TAG, "orderId : " + orderId);
        if (TextUtils.isEmpty(orderId)) {
            int payResult = PayResult.PAY_FAILURE;
            String payDesc = "无法获取订单号";
            notifyPayResult(payResult, payDesc);
            return;
        }
        retryQueryPayResultDelay(orderId, 0, 0);
    }

    /**
     * 延迟查询订单结果
     * @param orderId
     * @param times
     * @param delay
     */
    private void retryQueryPayResultDelay(final String orderId, final int times, long delay) {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                queryOrderResultRetry(orderId, times);
            }
        }, delay);
    }

    /**
     * 重试查询订单
     * @param orderId
     * @param times
     */
    private void queryOrderResultRetry(final String orderId, final int times) {
        Log.d(Log.TAG, "times : " + times);
        if (times > 3) {
            int payResult = PayResult.PAY_FAILURE;
            String payDesc = getActivity().getString(Utils.getStringId(getActivity(), "jy_unicon_activity_pay_fail"));
            notifyPayResult(payResult, payDesc);
            return;
        }
        mPayRequest.querySwiftPayResult(appId, channel, orderId, new ResponseCallback<JSONObject>() {
            @Override
            public void onCallback(Response<JSONObject> response) {
                Log.d(Log.TAG, "response : " + response);
                if (response == null || "-1".equals(response.getCode())) {
                    retryQueryPayResultDelay(orderId, times + 1, (times + 1) * 1000);
                } else {
                    if ("SUCCESS".equals(response.getCode())) {
                        int payResult = PayResult.PAY_SUCCESS;
                        String payDesc = getActivity().getString(Utils.getStringId(getActivity(), "jy_unicon_activity_pay_success"));
                        notifyPayResult(payResult, payDesc);
                    } else {
                        int payResult = PayResult.PAY_FAILURE;
                        String payDesc = getActivity().getString(Utils.getStringId(getActivity(), "jy_unicon_activity_pay_fail"));
                        notifyPayResult(payResult, payDesc);
                    }
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        mWebView.removeAllViews();
        mWebView.destroy();
        mWebView = null;
        super.onDestroy();
    }

    @Override
    public boolean onBackPressed() {
        showCancelPayDialog();
        return true;
    }

    private void showCancelPayDialog() {
        CancelPayDialog cancelPayDialog = new CancelPayDialog(getActivity());
        cancelPayDialog.setOnOkClickListener(new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String desc = getActivity().getString(Utils.getStringId(getActivity(), "jy_cancel_pay"));
                notifyPayResult(PayResult.PAY_CANCEL, desc);
            }
        });
        cancelPayDialog.show();
    }
}